/*
     Copyright 2007 Joseph M. Ferner

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.IO;
using NMock2;
using NUnit.Framework;

namespace OpenServers.Net.Common.FileSystem.Disk {
    [TestFixture]
    public class DiskDirectoryTest : BaseNMockTest {
        private DiskDirectory _diskDirectory;
        private string _tempPath;
        private string _dirPath;

        [SetUp]
        public override void SetUp() {
            base.SetUp();

            _tempPath = Path.GetTempPath() + "\\DiskDirectoryTest";
            Directory.CreateDirectory(_tempPath);
            _dirPath = _tempPath + "/test";
            Directory.CreateDirectory(_dirPath);
            _diskDirectory = new DiskDirectory(null, _dirPath);
        }

        [TearDown]
        public override void TearDown() {
            Directory.Delete(_tempPath, true);
            base.TearDown();
        }

        [Test]
        public void TestDirectoryInfoConstructor() {
            IDirectory directory = new DiskDirectory(null, new DirectoryInfo(_tempPath + "/test2"));
            Assert.IsNotNull(directory);
        }

        [Test]
        public void TestCreateDirectory() {
            IDirectory directory = _diskDirectory.CreateDirectory("test");
            Assert.IsNotNull(directory);
            Assert.AreEqual("test", directory.Name);
        }

        [Test]
        public void TestCreateFile() {
            IFile file = _diskDirectory.CreateFile("a.txt");
            Assert.IsNotNull(file);
            Assert.AreEqual("a.txt", file.Name);
        }

        [Test]
        public void TestCreate() {
            DiskDirectory dir = new DiskDirectory(null, _tempPath + "\\test2");
            dir.Create();
            Assert.AreEqual(true, Directory.Exists(_tempPath + "\\test2"));
        }

        [Test]
        public void TestGetDirectoriesEmpty() {
            IList<IDirectory> dirs = _diskDirectory.GetDirectories();
            Assert.AreEqual(0, dirs.Count);
        }

        [Test]
        public void TestGetDirectoriesWithDir() {
            Directory.CreateDirectory(_dirPath + "/child");

            IList<IDirectory> dirs = _diskDirectory.GetDirectories();
            Assert.AreEqual(1, dirs.Count);
            Assert.AreEqual("child", dirs[0].Name);
        }

        [Test]
        public void TestGetDirectoriesWithFile() {
            File.WriteAllText(_dirPath + "/a.txt", "hello");

            IList<IDirectory> dirs = _diskDirectory.GetDirectories();
            Assert.AreEqual(0, dirs.Count);
        }

        [Test]
        public void TestGetItemsEmpty() {
            IList<IFileSystemObject> children = _diskDirectory.GetItems();
            Assert.AreEqual(0, children.Count);
        }

        [Test]
        public void TestGetItemsWithDir() {
            Directory.CreateDirectory(_dirPath + "/child");

            IList<IFileSystemObject> children = _diskDirectory.GetItems();
            Assert.AreEqual(1, children.Count);
            Assert.AreEqual("child", children[0].Name);
        }

        [Test]
        public void TestGetItemsWithFile() {
            File.WriteAllText(_dirPath + "/a.txt", "hello");

            IList<IFileSystemObject> children = _diskDirectory.GetItems();
            Assert.AreEqual(1, children.Count);
            Assert.AreEqual("a.txt", children[0].Name);
        }

        [Test]
        public void TestMoveTo() {
            IDirectory newDir = Mocks.NewMock<IDirectory>();
            IDirectory newChildDir = Mocks.NewMock<IDirectory>();
            IFile bTxtFile = Mocks.NewMock<IFile>();
            IFile aTxtFile = Mocks.NewMock<IFile>();

            Directory.CreateDirectory(_dirPath + "/child");
            File.WriteAllText(_dirPath + "/a.txt", "a.txt content");
            File.WriteAllText(_dirPath + "/child/b.txt", "b.txt content");

            Expect.Once.On(newDir).Method("CreateDirectory").With("child").Will(Return.Value(newChildDir));
            Expect.Once.On(newChildDir).Method("CreateFile").With("b.txt").Will(Return.Value(bTxtFile));
            Expect.Once.On(newDir).Method("CreateFile").With("a.txt").Will(Return.Value(aTxtFile));

            MemoryStream bTxtFileStream = new MemoryStream();
            Expect.Once.On(bTxtFile).Method("OpenOutputStream").Will(Return.Value(bTxtFileStream));

            MemoryStream aTxtFileStream = new MemoryStream();
            Expect.Once.On(aTxtFile).Method("OpenOutputStream").Will(Return.Value(aTxtFileStream));

            _diskDirectory.MoveTo(newDir);
        }

        [Test]
        public void TestMoveToFile() {
            IFile file = Mocks.NewMock<IFile>();

            try {
                _diskDirectory.MoveTo(file);
                Assert.Fail("should throw an error");
            } catch (Exception) {
                //ok
            }
        }

        [Test]
        public void TestParentOnRoot() {
            DiskDirectory dir = new DiskDirectory(null, "c:\\");
            Assert.IsNull(dir.Parent);
        }
    }
}
